package com.yxb.cms.architect.utils;

import lombok.extern.log4j.Log4j2;
import org.apache.commons.codec.Charsets;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.HmacAlgorithms;
import org.apache.commons.codec.digest.HmacUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 开放API接口签名工具类
 * @author yangbingbing
 */
@Log4j2
public class OpenApiUtil {

    /**
     * 生成签名验证
     * @param appKey        授权Key
     * @param timeStamp     时间戳
     * @param paras         十六进制加密参数
     * @param appSecret     密匙
     */
    public static String genSign(String appKey, String timeStamp, String paras, String appSecret) {
        String source = appKey + timeStamp + paras;
        HmacUtils hmacUtils = new HmacUtils(HmacAlgorithms.HMAC_SHA_1, appSecret.getBytes(Charsets.UTF_8));
        return Hex.encodeHexString(hmacUtils.hmac(source.getBytes(Charsets.UTF_8)), false);
    }

    /**
     * 生成参数 加密字符串
     * @param params        参数
     * @param appSecret     密匙
     */
    public static String hexParas(Map<String, Object> params, String appSecret) throws Exception {
        String data = OpenApiUtil.joinMap(params, "=", "&");
        try {
            return HexUtil.encrypt(data, "UTF-8", Hex.encodeHexString(appSecret.getBytes(Charsets.UTF_8)));
        } catch (Exception e) {
            log.error(e.getMessage(),e);
            throw e;
        }
    }

    private static String joinMap(Map<String, Object> params, String keyValSeparator, String pairSeparator){
        if (MapUtils.isEmpty(params)) {
            return StringUtils.EMPTY;
        }
        List<String> keyVals = new ArrayList<>();
        for(Map.Entry<String, Object> e : params.entrySet()){
            keyVals.add(e.getKey()+keyValSeparator+e.getValue());
        }
        return StringUtils.join(keyVals, pairSeparator);
    }

    /**
     * 参数转换为Map
     * @param param 参数
     */
    public static Map<String, Object> getMapParams(String param) {
        Map<String, Object> map = new HashMap<>(0);
        if (StringUtils.isBlank(param)) {
            return map;
        }
        String[] params = param.split("&");
        for (String param1 : params) {
            String[] p = param1.split("=");
            if (p.length == 2) {
                map.put(p[0], p[1]);
            }
        }
        return map;
    }
}
